package com.base.moduleUser.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.base.core.common.http.HttpStatus;
import com.base.core.common.http.response.AjaxResult;
import com.base.core.common.utils.JwtUtils;
import com.base.core.common.utils.MD5Util;
import com.base.core.common.utils.UserContext;
import com.base.core.domain.User;
import com.base.core.exception.BusinessException;
import com.base.core.exception.enums.UserErrorCode;
import com.base.moduleUser.dto.RegisterDto;
import com.base.moduleUser.dto.UpdateLocationDto;
import com.base.moduleUser.service.UserService;
import com.base.moduleUser.mapper.UserMapper;
import com.base.moduleUser.vo.UserLoginVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
* @author XinyuZhao
* @description 针对表【user(用户表)】的数据库操作Service实现
* @createDate 2025-06-19 11:07:16
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private JwtUtils jwtUtils;
    @Override
    public UserLoginVo login(User user) throws BusinessException {
        /**
         * 1. 校验用户名和密码
         * 2. 登录成功，生成token，refreshToken，并存入redis
         * 3. 返回token
         * 4. 登录失败，返回错误信息
         */
        //1.校验用户名
        String username = user.getUsername();
        Wrapper<User> wrapper = new QueryWrapper<User>().eq("username", username);
        User user1 = userMapper.selectOne(wrapper);
        if(ObjectUtils.isNull(user1)){
                throw new BusinessException(UserErrorCode.USER_NOT_FOUND);
        }
        //2.校验密码
        String password = MD5Util.md5(user.getPassword());
        if(!password.equals(user1.getPassword())){
                throw new BusinessException(UserErrorCode.LOGIN_FAILED);
        }
        //3.登录成功，生成token，refreshToken，并存入redis
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", user1.getId());
        claims.put("username", user1.getUsername());
        String token =jwtUtils.generateToken(user1.getUsername().toString(), claims);
       String refreshToken = jwtUtils.generateRefreshToken(user1.getId().toString(), claims);
        redisTemplate.opsForValue().set("user:token:"+user1.getUsername(), user1);
        redisTemplate.opsForValue().set("user:refreshToken:"+user1.getId(), user1);
        UserLoginVo userLoginVO = new UserLoginVo();
        userLoginVO.setToken(token);
        userLoginVO.setRefreshToken(refreshToken);
        userLoginVO.setUsername(user1.getUsername());
        userLoginVO.setId(user1.getId());

        return userLoginVO;
    }

    @Override
    public AjaxResult register(RegisterDto registerDto) {
        /**
         * 1.插入用户信息
         * 2，加密密码
         * 2.返回注册成功信息
         */
        registerDto.setPassword(MD5Util.md5(registerDto.getPassword()));
        userMapper.insert(registerDto);
        return AjaxResult.success("注册成功");
    }

    @Override
    public void delete(User user2) {
        user2.setId(2l);
        userMapper.deleteById(user2.getId());
    }

    @Override
    public void cash(User user3) {
        redisTemplate.opsForValue().set("user:"+user3.getId(), user3);
    }


    /**
     * 根据用户名获取用户信息
     */
    @Override
    public User getUserByUsername(String username) {
        User user=userMapper.selectOne(new QueryWrapper<User>().eq("username", username));
        return user;
    }


    @Override
    public AjaxResult getCaptcha(String phone) {
        /**
         * 1.生成code
         * 2.发送验证码
         * 3.存入redis
         * 4.返回验证码
         */
        log.info("phone"+phone);
        //生成验证码
        int coderandom = 1234;
        String code=String.valueOf(coderandom);
        try {
            //SmsUtil.sendSms(phone, code);
            log.info("验证码发送成功");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        // 1. 存储验证码（String 结构，独立过期）
        redisTemplate.opsForValue().set(
                "sms_code:" + phone,
                code,
                10, TimeUnit.MINUTES
        );
        // 2. 将手机号存入 Sorted Set（Score=过期时间戳）
        redisTemplate.opsForZSet().add(
                "sms_code_expire_tracker",
                phone,
                System.currentTimeMillis() + 10 * 60 * 1000
        );

        return AjaxResult.success();
    }
    /**
     * 校验验证码
     */
    @Override
    public AjaxResult verifyCaptcha(String phone, String captcha) {
        String code = (String) redisTemplate.opsForValue().get("sms_code:" + phone);
        if (code == null) {
            return AjaxResult.error("验证码已过期");
        }
        if (!code.equals(captcha)) {
            return AjaxResult.error("验证码错误");
        }
        return AjaxResult.success("验证码正确");
    }

    /**
     * 更新用户位置
     */
    @Override
    public void updateLocation(UpdateLocationDto updateLocationDto) {
        User user=this.getById(UserContext.getCurrentUserId());
        user.setLastLocationPoint(updateLocationDto.getLastLocationPoint());
        user.setLastLocationAt(new Date());
        user.setLocation(updateLocationDto.getLocation());
        this.updateById(user);
    }


}




